package com.geline.luckysheet.util;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.sql.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * 日期转换
 * 参考：https://blog.csdn.net/qq_41057885/article/details/126629606
 * 用法1：@ExcelProperty(value = {"添加日期"}, converter = BaseDateConverter.LocalDateTimeConverter.class)
 * 用法2：ExcelWriter writer = EasyExcel.write(response.getOutputStream()).needHead(true).excelType(ExcelTypeEnum.XLSX)
 *           .registerConverter(new BaseDateConverter.LocalDateConverter())
 *           .build();
 * @author: mengxin
 * @date: 2022/10/16 11:39
 */
public class BaseDateConverter {

    /**
     * 核心抽象类，负责不同类的数据类型装换
     * @param <T> LocalXXX类泛型
     */
    private static abstract class CoreConverter<T> implements Converter<T> {

        private Class<T> clazz;

        /**
         * 指定Class类型，接收LocalDate.class，LocalTime.class，LocalDateTime.class
         */
        public CoreConverter(Class<T> clazz) {
            this.clazz = clazz;
        }

        /**
         * 导入支持的数据类型
         */
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return CellDataTypeEnum.STRING;
        }

        /**
         * 导出支持的数据类型
         */
        @Override
        public Class supportJavaTypeKey() {
            return clazz;
        }

        /**
         * 导入时，数据类型转换
         * @param cellData excel单元格数据
         * @param property 单元格样式
         * @param config 全局配置
         * @return
         */
        @Override
        public T convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty property, GlobalConfiguration config) throws Exception {
            if (cellData.getData() instanceof LocalDate) {// LocalDate日期转换
                return (T) LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } else if (cellData.getData() instanceof LocalTime) {// LocalTime时间转换
                return (T) LocalTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("HH:mm:ss"));
            } else if (cellData.getData() instanceof LocalDateTime) {// LocalDateTime时间日期转换
                return (T) LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            return null;
        }

        /**
         * 导出时，数据类型转换
         * @param obj 当前数据
         * @param property 单元格样式
         * @param config 全局配置
         * @return
         */
        @Override
        public WriteCellData<?> convertToExcelData(T obj, ExcelContentProperty property, GlobalConfiguration config) throws Exception {
            if (obj instanceof LocalDate) {// LocalDate日期转换
                return new WriteCellData<>(((LocalDate) obj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            } else if (obj instanceof LocalTime) {// LocalTime时间转换
                return new WriteCellData<>(((LocalTime) obj).format(DateTimeFormatter.ofPattern("HH:mm:ss")));
            } else if (obj instanceof LocalDateTime) {// LocalDateTime时间日期转换
                return new WriteCellData<>(((LocalDateTime) obj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            return new WriteCellData<>(obj.toString());
        }
    }

    /**
     * java.sql.Date数据类型转换器，查询返回List<Map>会使用
     */
    public static class JavaSqlDateConverter extends CoreConverter<Date> {
        public JavaSqlDateConverter() {
            super(Date.class);
        }
    }

    /**
     * LocalDate数据类型转换器
     */
    public static class LocalDateConverter extends CoreConverter<LocalDate> {
        public LocalDateConverter() {
            super(LocalDate.class);
        }
    }

    /**
     * LocalTime数据类型转换器
     */
    public static class LocalTimeConverter extends CoreConverter<LocalTime> {
        public LocalTimeConverter() {
            super(LocalTime.class);
        }
    }

    /**
     * LocalDateTime数据类型转换器
     */
    public static class LocalDateTimeConverter extends CoreConverter<LocalDateTime> {
        public LocalDateTimeConverter() {
            super(LocalDateTime.class);
        }
    }
}
